// Copyright (c) 2016, Open DICOMweb Project. All rights reserved.
// Use of this source code is governed by the open source license
// that can be found in the LICENSE file.
// Author: Jim Philbin <jfphilbin@gmail.edu>
// See the AUTHORS file for other contributors.

import 'package:dicom_core/src/dicom.dart';
import 'package:dicom_core/src/dataset/base/root_dataset.dart';
import 'package:dicom_core/src/dataset/errors.dart';
import 'package:dicom_core/src/entity/entity.dart';
import 'package:dicom_core/src/entity/ie_level.dart';
import 'package:dicom_core/src/entity/instance.dart';
import 'package:dicom_core/src/entity/patient/patient.dart';
import 'package:dicom_core/src/entity/study.dart';
import 'package:dicom_core/src/uid/uid.dart';

/// A DICOM [Series] Instance in SOP Instance format.
class Series extends Entity {
  /// Creates a  [Series].
  Series(Study study, Uid uid, RootDataset rds, [Map<Uid, Instance>? instances])
      : super(study, uid, rds, (instances == null) ? {} : instances);

  /// Returns a copy of _this_ [Series], but with a  [Uid]. If [parent]
  /// is _null_ the  [Instance] is in the same [Series] as _this_.
  Series.from(Series series, RootDataset rds, [Study? parent])
      : super((parent == null) ? series.parent : parent,  Uid(), rds,
             Map.from(series.children));

  /// Returns a  [Series] created from the [RootDataset].
  factory Series.fromRootDataset(RootDataset rds, Study study) {
    assert(study != null);
    final e = rds[kSeriesInstanceUID];
    if (e == null) return elementNotPresentError(e);
    final seriesUid =  Uid(e.value);
    final series =  Series(study, seriesUid, rds);
    study.putIfAbsent(series);
    return series;
  }

  @override
  IELevel get level => IELevel.series;

  @override
  Type get parentType => Study;

  @override
  Type get childType => Instance;

  @override
  String get path => '/${study?.path}/$uid';

  @override
  String get fullPath => '/${study?.fullPath}/$uid';

  @override
  String get info => '''$this
  $study
    $subject
  ''';

  /// Returns the [Study] that is the [parent] of _this_ Series.
  Study? get study => parent as Study;

  /// Returns the [Study] that is the [parent] of _this_ Series.
  Patient? get subject => study?.subject as Patient;

  get instances => children?.values;

  Instance createInstanceFromRootDataset(RootDataset rds) =>
       Instance.fromRDS(rds, this);
}
